package org.mule.transport.ftpext;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.net.ftp.FTP;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import org.mule.api.MuleMessage;
import org.mule.api.construct.FlowConstruct;
import org.mule.api.endpoint.InboundEndpoint;
import org.mule.api.lifecycle.CreateException;
import org.mule.api.transport.Connector;

import org.mule.transport.ConnectException;
import org.mule.transport.ftp.FtpMessageReceiver;

public class FtpExtMessageReceiver extends FtpMessageReceiver {

    FtpExtConnector extConnector;

    public FtpExtMessageReceiver(Connector connector,
            FlowConstruct flowConstruct,
            InboundEndpoint endpoint,
            long frequency) throws CreateException {
        super(connector, flowConstruct, endpoint, frequency);
        extConnector = (FtpExtConnector) connector;
    }

    @Override
    protected void processFile(FTPFile file) throws Exception {
        try {
            extConnector.acquireInboundFtpConnectionPermit();
            super.processFile(file);
        } finally {
            extConnector.releaseInboundFtpConnectionPermit();
        }

    }

    @Override
    protected void postProcess(FTPClient client, FTPFile file, MuleMessage message) throws Exception {
        //FtpExtConnector extConnector = (FtpExtConnector) connector;
        String moveToPattern = extConnector.getMoveToPattern();
        String destinationFileName = null;
        if (moveToPattern != null) {
            destinationFileName = extConnector.getFilenameParser().getFilename(message,
                    moveToPattern);
        }
        String moveToDirectory = extConnector.getMoveToDirectory();
        if (moveToDirectory != null && moveToPattern != null) {
            
            client.rename(file.getName(),moveToDirectory+"/"+destinationFileName);
//            EndpointURI endpointURI = endpoint.getEndpointURI();
//            FTPClient destClient = null, srcClient = null;
//            try {
//                destClient = getFTPClient(endpointURI.getHost(), endpointURI.getPort(),
//                        moveToDirectory, endpointURI.getUser(), endpointURI.getPassword(),
//                        extConnector.isBinary(), extConnector.isPassive());
//                srcClient = getFTPClient(endpointURI.getHost(), endpointURI.getPort(),
//                        endpointURI.getPath(), endpointURI.getUser(), endpointURI.getPassword(),
//                        extConnector.isBinary(), extConnector.isPassive());
//                //destClient.listFiles();
//
//                //InputStream is = srcClient.retrieveFileStream(file.getName());
//                //destClient.storeFile(destinationFileName, is);
//                //is.close();
//            } finally {
//                if (srcClient != null) {
//                    //srcClient.completePendingCommand();
//                    srcClient.logout();
//                    srcClient.disconnect();
//                }
//                if (destClient != null) {
//                    //destClient.completePendingCommand();
//                    destClient.logout();
//                    destClient.disconnect();
//                }
//            }


        }
        boolean doNotDelete = extConnector.getDoNotDelete();
        if (!doNotDelete) {
            if (!client.deleteFile(file.getName())) {
                throw new IOException(MessageFormat.format("Failed to delete file {0}. Ftp error: {1}",
                        file.getName(), client.getReplyCode()));
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Deleted processed file " + file.getName());
            }
        }
        if (connector.isStreaming()) {
            if (!client.completePendingCommand()) {
                throw new IOException(MessageFormat.format("Failed to complete a pending command. Retrieveing file {0}. Ftp error: {1}",
                        file.getName(), client.getReplyCode()));
            }
        }
    }

    @Override
    protected FTPFile[] listFiles() throws Exception {
        FTPClient client = null;
        //FtpExtConnector extConnector = (FtpExtConnector) connector;
        try {
            try {
                client = extConnector.createFtpClient(endpoint);

            } catch (Exception e) {
                throw new ConnectException(e, this);
            }
            FTPFile[] files = client.listFiles();

            if (!FTPReply.isPositiveCompletion(client.getReplyCode())) {
                throw new IOException("Failed to list files. Ftp error: " + client.getReplyCode());
            }

            if (files == null || files.length == 0) {
                return files;
            }

            List<FTPFile> v = new ArrayList<FTPFile>();
            long now = System.currentTimeMillis();

            long before = now - extConnector.getFileAge();

            boolean checkFileAge = extConnector.getCheckFileAge();
            for (FTPFile file : files) {
                if (file.isFile()) {

                    if ((!checkFileAge) || (file.getTimestamp().getTimeInMillis() < before)) {
                        if (filenameFilter == null || filenameFilter.accept(null, file.getName())) {
                            v.add(file);
                        }
                    }
                }
            }

            return v.toArray(new FTPFile[v.size()]);
        } finally {
            if (client != null) {
                connector.releaseFtp(endpoint.getEndpointURI(), client);
            }
        }
    }

//    protected FTPClient getFTPClient(String host, int port, String path,
//            String user, String password, boolean isBinary, boolean isPassive) throws Exception {
//
//        FTPClient client = new FTPClient();
//        if (port > 0) {
//            client.connect(host, port);
//        } else {
//            client.connect(host);
//        }
//        if (!FTPReply.isPositiveCompletion(client.getReplyCode())) {
//            throw new IOException("Ftp connect failed: " + client.getReplyCode());
//        }
//        if (!client.login(user, password)) {
//            throw new IOException("Ftp login failed: " + client.getReplyCode());
//        }
//
//        //------------
//        int type = FTP.BINARY_FILE_TYPE;
//        if (!isBinary) {
//            type = FTP.ASCII_FILE_TYPE;
//        }
//        if (!client.setFileType(type)) {
//            throw new IOException("Ftp error. Couldn't set BINARY/ASCII transfer type: " + client.getReplyCode());
//        }
//        //-------------
//        if (isPassive) {
//            client.enterLocalPassiveMode();
//        } else {
//            client.enterLocalActiveMode();
//        }
//
//        if (!client.changeWorkingDirectory(path)) {
//            throw new IOException("Ftp error. Couldn't change path to: " + path + "-" + client.getReplyCode());
//        }
//        return client;
//
//    }
}
